#include "func.h"

int recvn(int sockfd, void *buf, int length){
    int total = 0;
    char *p = (char *)buf;
    while(total < length){
        ssize_t sret = recv(sockfd, p+total, length-total, 0);
        total += sret;
    }
    return total;
}

int recvFile(int sockfd,char* bufc){
/////////////////////////////////////////////
    char bufcname[1024];
    strcpy(bufcname,bufc);
    int judgefd =open("bufcname",O_RDWR);
    if(!judgefd){
    train_t train;
    memset(&train, 0, sizeof(train));
    struct stat statbuf;
    train.length = sizeof(int);
    fstat(judgefd,&statbuf);
    char bufi[1024];
    sprintf(bufi,"%ld",statbuf.st_size);
    strcpy(train.data,bufi);
    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);
    printf("发送了无断点版本%s\n",bufi);
    }else{
    train_t train;
    memset(&train, 0, sizeof(train));
    struct stat statbuf;
    train.length = sizeof(int);
    printf("filename:%s",bufcname);
    stat(bufcname,&statbuf);
    char bufi[1024];
    sprintf(bufi,"%ld",statbuf.st_size);
    printf("读到的statbuf数据：%ld",statbuf.st_size);
    strcpy(train.data,bufi);
    printf("发送了有断点版本：%s\n",bufi);
    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);

    }
//////////////////////////////////////////////
    char filename[1024] = {0};
    int length;
    recvn(sockfd, &length, sizeof(length));
    recvn(sockfd, filename, length);
    off_t filesize;
    recvn(sockfd, &length, sizeof(length));
    recvn(sockfd, &filesize, length);
    printf("filesize = %ld\n", filesize);
    int fd = open(filename, O_RDWR|O_CREAT, 0666);
    off_t cursize = 0;
    off_t slice = filesize/10000;
    off_t lastsize = 0;
    while(1){
        char buf[4096] = {0};
        recvn(sockfd, &length, sizeof(length));
        if(length != 1000){
            printf("length = %d\n", length);
        }
        if(length == 0){
            break;
        }
        recvn(sockfd, buf, length);
        write(fd, buf, length);

        cursize += length;
        if(cursize - lastsize > slice){
            printf("%5.2lf%%\r",100.0*cursize/filesize);
            fflush(stdout);//将stdout缓冲区的数据刷到文件对象里面
            lastsize = cursize;
        }
    }
    printf("100.00%%\n");
    close(fd);
    return 0;
}

int putsFile(int sockfd, const char *filename)
{
    train_t train;
    memset(&train, 0, sizeof(train));
    train.length = strlen(filename);
    strcpy(train.data, filename);
    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);

    int fd = open(filename, O_RDWR);

    struct stat statbuf;
    fstat(fd,&statbuf);

    train.length = sizeof(statbuf.st_size);
    memcpy(train.data,&statbuf.st_size,train.length);
    send(sockfd,&train,sizeof(int)+train.length,MSG_NOSIGNAL);

    char *p = (char *)mmap(NULL,statbuf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    ERROR_CHECK(p,MAP_FAILED,"mmap");

    off_t totalsize = 0;

    while(totalsize < statbuf.st_size)
    {
        if(statbuf.st_size>1000)
        {
            train.length = 1000;
        }
        else
        {
            train.length = statbuf.st_size-totalsize;
        }
        send(sockfd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
        send(sockfd,p+totalsize,train.length,MSG_NOSIGNAL);
        totalsize += train.length;
    }
    train.length = 0;
    send(sockfd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
    munmap(p,statbuf.st_size);
    close(fd);
    return 0;
}
int getcmd(const char *buf){
    if(strcmp(buf,"cd")==0) return CD;
    if(strcmp(buf,"ls")==0) return LS;
    if(strcmp(buf,"gets")==0) return GETS;
    if(strcmp(buf,"puts")==0) return PUTS;
    if(strcmp(buf,"remove")==0) return REMOVE;
    if(strcmp(buf,"pwd")==0) return PWD;
    if(strcmp(buf,"mkdir")==0) return MKDIR;
    if(strcmp(buf,"rmdir")==0) return RMDIR;
    else return -1;
}
void userLogin(int sockfd){
    char username[4096] = {0};
    char salt[4096] = {0};
    char *passwd;
    char miwen[4096] = {0};
    while(1){
        memset(username, 0, sizeof(username));
        printf("username:");
        scanf("%s", username);
        //传用户名
        train_t train;
        memset(&train, 0, sizeof(train));
        train.length = strlen(username);
        strcpy(train.data, username);
        send(sockfd, &train, 4+train.length, MSG_WAITALL);

        //接受盐值
        int buflen = 0;
        char buf[4096];
        recv(sockfd, &buflen, 4, MSG_WAITALL);
        recv(sockfd, buf, buflen, MSG_WAITALL);
        if(buf[0] != '$'){
            printf("please input right username!\n");
            continue;
        } else {
            //输密码得到密文
            passwd = getpass("passwd:");
            strcpy(salt, buf);
            strcpy(miwen, crypt(passwd, salt));
            //传密文
            memset(&train, 0, sizeof(train));
            train.length = strlen(miwen);
            strcpy(train.data, miwen);
            send(sockfd, &train, 4+train.length, MSG_WAITALL);
            //接受返回的验证消息
            memset(&buf, 0, sizeof(buf));
            recv(sockfd, &buflen, 4, MSG_WAITALL);
            recv(sockfd, buf, buflen, MSG_WAITALL);
            if(buf[0] == 'y'){
                printf("welcom!\n");
                return;
            } else {
                printf("wrong passwd\n");
                continue;
            }
        }
    }
}

int logrecord(char* order){
    char buf[1024];
    memset(buf,0, sizeof(buf));
    strcpy(buf,order);
    time_t curtime =time(NULL);
    char* printtime=ctime(&curtime);
    char nowtime[1024];
    strncpy(nowtime,printtime, strlen(printtime)-1);
    FILE *fp;
    fp=fopen("./log","a+");
    if(!fp)
    {
        fp = fopen("./log","w+");
    }
    char mid[10]=" --> ";
    strcat(nowtime,mid);
    strcat(nowtime,buf);
    fputs(nowtime,fp);
    memset(nowtime,0, sizeof(nowtime));
    fclose(fp);
    return 0;
}

